<!--日历-->
<template>
    <div class="calendar">
        <div class="header">
            <!-- <svg @click="lastYear" t="1696835230584" class="icon" viewBox="0 0 1024 1024" version="1.1"
        xmlns="http://www.w3.org/2000/svg" p-id="4146" width="20" height="420">
        <path
          d="M602.496 512l338.752 338.752-90.496 90.496L421.504 512l429.248-429.248 90.496 90.496L602.496 512z m-320 0l338.752 338.752-90.496 90.496L101.504 512l429.248-429.248 90.496 90.496L282.496 512z"
          fill="#666666" p-id="4147"></path>
      </svg> -->
            <!-- <svg @click="lastData" t="1696835422566" class="icon" viewBox="0 0 1024 1024" version="1.1"
        xmlns="http://www.w3.org/2000/svg" p-id="10525" width="20" height="20">
        <path d="M474.496 512l338.752-338.752-90.496-90.496L293.504 512l429.248 429.248 90.496-90.496z" fill="#666666"
          p-id="10526"></path>
      </svg> -->
            <span class="fontS" style="padding: 0 20px;text-align: center;">
                <div>{{ year }}年{{ month }}月{{ day }}日</div>
                <!-- <div> {{ lunar }}</div> -->
            </span>
            <button @click="lastData">上月</button>
            <button @click="todayData" style="margin: 0 5px;">今日</button>
            <button @click="nextData">下月</button>
            <!-- <svg @click="nextData" t="1696835373514" class="icon" viewBox="0 0 1024 1024" version="1.1"
        xmlns="http://www.w3.org/2000/svg" p-id="9493" width="20" height="20">
        <path d="M369.5 980.9l-81.8-73.6 354.4-393.8-375-394.7L346.9 43l445 468.5z" p-id="9494" fill="#515151"></path>
      </svg> -->
            <!-- <svg @click="nextYear" t="1696835190544" class="icon" viewBox="0 0 1024 1024" version="1.1"
        xmlns="http://www.w3.org/2000/svg" p-id="4007" width="20" height="20">
        <path
          d="M741.504 512L402.752 173.248l90.496-90.496L922.496 512l-429.248 429.248-90.496-90.496L741.504 512z m-320 0L82.752 173.248l90.496-90.496L602.496 512l-429.248 429.248-90.496-90.496L421.504 512z"
          fill="#666666" p-id="4008"></path>
      </svg> -->
        </div>
        <div class="body fontS">
            <div v-for="item in weekData">{{ item }}</div>
            <div v-for="i in monthData" @click="monthDataFun(i)" class="current-month-day" :class="{
                'dateDayStyle': i.typenum == 2 ? dateDay == i.value : '',
            }">
                <div v-if="i.typenum == 2" :class="i.type">{{ i.value }}</div>
                <div v-if="i.typenum == 2" :class="i.type" style="font-size: 12px">{{ i.lday }}</div>
            </div>
        </div>
    </div>
</template>

<script>
export default {
    name: "name",
    data() {
        return {
            weekData: ['一', '二', '三', '四', '五', '六', '日'],
            monthData: [],
            year: new Date().getFullYear(),
            month: new Date().getMonth() + 1,
            day: new Date().getDate(),
            lunar: '',
            dateDay: ''
        }
    },
    mounted() {
        this.getRandomData(this.year, this.month);

    },
    methods: {
        monthDataFun(e) {
            if (e.typenum == 2) {
                this.dateDay = e.value; this.day = e.value
                let dateItem = this.year + '-' + this.month + '-' + e.value
                this.$emit('calendarFun', dateItem)
            }


        },
        lastYear() {
            this.year--;
            this.monthData = [];
            this.getRandomData(this.year, this.month);
        },
        nextYear() {
            this.year++;
            this.monthData = [];
            this.getRandomData(this.year, this.month);
        },
        lastData() {
            this.dateDay = ''
            this.month--;
            if (this.month == 0) {
                this.year = parseInt(this.year) - 1;
                this.month = 12;
            }
            if (Number(this.month) < 10) {
                this.month = '0' + this.month;
            }
            this.monthData = [];
            this.getRandomData(this.year, this.month);
        },
        nextData() {
            this.dateDay = ''
            this.month++;
            if (this.month == 13) {
                this.year = parseInt(this.year) + 1;
                this.month = 1;
            }
            if (Number(this.month) < 10) {
                this.month = '0' + this.month;
            }
            this.monthData = [];
            this.getRandomData(this.year, this.month);
        },
        todayData() {
            const date = new Date();
            const nowYear = date.getFullYear();
            const nowMonths = date.getMonth() + 1;
            this.year = nowYear
            if (nowMonths < 10) {
                this.month = '0' + nowMonths;
            } else {
                this.month = nowMonths
            }
            this.monthData = [];
            this.getRandomData(nowYear, nowMonths)
        },
        //  获取任意月份一号是周几,以及任意月的天数
        getFirstDayWeek(year, nowMonth) {
            //获取当前月的上一月
            var year2 = year;
            var month2 = parseInt(nowMonth) - 1;
            if (month2 == 0) {
                year2 = parseInt(year2) - 1;
                month2 = 12;
            }
            if (month2 < 10) {
                month2 = "0" + month2;
            }
            const preMonth = year2 + "-" + month2;
            //获取上一月有多少天
            const lastDateNum = new Date(Number(year2), Number(month2), 0);
            const lastTimeNUm = lastDateNum.getDate();

            //获取当前月有多少天
            const dateNum = new Date(year, nowMonth, 0);
            const timeNUm = dateNum.getDate();
            //获取当前月一号星期几
            const weekList = [0, 1, 2, 3, 4, 5, 6]
            const res = new Date(nowMonth + '/' + 1 + '/' + year);
            const reNum = weekList[res.getDay()]//获取当前月1号是星期几

            return {
                lastTimeNUm,
                timeNUm,
                reNum
            }
        },
        totimes(item) {
            var datetime = new Date(item)
            var year = datetime.getFullYear();
            var month = datetime.getMonth() + 1;//js从0开始取 
            var date = datetime.getDate();
            month = month < 10 ? "0" + month : month;
            date = date < 10 ? "0" + date : date;
            return year + "-" + month + "-" + date

        },
        //  获取任意月的日期数据
        getRandomData(year, nowMonth) {
            const {
                lastTimeNUm,
                timeNUm,
                reNum
            } = this.getFirstDayWeek(year, nowMonth);

            const langth = reNum == 0 ? 6 : (reNum - 1);
            for (let i = lastTimeNUm - langth + 1; i <= lastTimeNUm; i++) {
                const { lday } = this.getLunar(this.year, this.month, i);
                this.monthData.push({
                    id: Date.now(),
                    typenum: 1,
                    value: i,
                    festival: '',
                    placeHolder: '',
                    type: "last-month-day",
                    lday
                })
            }

            const date = new Date();
            const nowYear = date.getFullYear();
            const nowMonths = date.getMonth() + 1;
            const nowData = date.getDate();
            let type = 'current-month-day';
            const s = (nowYear + '-' + nowMonths + '-' + nowData);

            for (let i = 1; i <= timeNUm; i++) {
                const y = (this.year + '-' + this.month + '-' + i)
                const { lunar_month_day, lday } = this.getLunar(this.year, this.month, i);
                if (nowData == i) this.lunar = lunar_month_day;

                type = this.totimes(s) == this.totimes(y) ? 'current-day' : '';
                this.monthData.push({
                    id: Date.now(),
                    value: i,
                    typenum: 2,
                    festival: '',
                    placeHolder: '',
                    type,
                    lday
                })
            }
            const datas = 42 - this.monthData.length;
            if (42 - this.monthData.length > 0) {
                for (let i = 1; i <= datas; i++) {
                    const { lday } = this.getLunar(this.year, this.month, i);
                    this.monthData.push({
                        id: Date.now(),
                        value: i,
                        typenum: 3,
                        festival: '',
                        placeHolder: '',
                        type: "next-month-day",
                        lday
                    })
                }
            }

        },


        //  获取阴历
        /**获取阴历 start*/
        getLunar(year, nowMonth, day) {
            var nyear;
            var nmonth;
            var nday = -1;
            var nwday;

            var lmonth, lday, lleap; //农历参数
            function Draw() {
                NewTick(year, nowMonth, day);

                var lunar_month_day = lmonth + "月" + lday;
                //需要展示在页面地方
                return { lunar_month_day, lday }
            }


            function NewTick(year, nowMonth, day) {
                let noww = new Date(year + '-' + nowMonth + '-' + day);
                if (noww.getDate() != nday) {
                    nyear = noww.getFullYear();
                    nmonth = noww.getMonth() + 1;
                    nwday = noww.getDay();
                    nday = noww.getDate();
                    getlunar(); //获取农历
                }
                // nhrs = noww.getHours();
                // nmin = noww.getMinutes();
                // nsec = noww.getSeconds();

            }


            //阴历函数开始
            var lunarInfo = new Array(0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2, 0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977, 0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970, 0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950, 0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557, 0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0, 0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0, 0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6, 0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570, 0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, //1990
                0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5, 0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930, 0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530, 0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45, 0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0, 0x14b63);

            function lYearDays(y) {
                var i, sum = 348;
                for (i = 0x8000; i > 0x8; i >>= 1) sum += (lunarInfo[y - 1900] & i) ? 1 : 0;
                return (sum + leapDays(y));
            }

            function leapDays(y) {
                if (leapMonth(y)) return ((lunarInfo[y - 1900] & 0x10000) ? 30 : 29);
                else return (0);
            }

            function leapMonth(y) {
                return (lunarInfo[y - 1900] & 0xf);
            }

            function monthDays(y, m) {
                return ((lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29);
            }

            function Lunar(y, m, d) {
                var i, leap = 0,
                    temp = 0;
                var offset = (Date.UTC(y, m, d) - Date.UTC(1900, 0, 31)) / 86400000;
                for (i = 1900; i < 2050 && offset > 0; i++) {
                    temp = lYearDays(i);
                    offset -= temp;
                }
                if (offset < 0) {
                    offset += temp;
                    i--;
                }
                this.year = i;
                leap = leapMonth(i);
                this.isLeap = false;
                for (i = 1; i < 13 && offset > 0; i++) {
                    if (leap > 0 && i == (leap + 1) && this.isLeap == false) {
                        --i;
                        this.isLeap = true;
                        temp = leapDays(this.year);
                    } else {
                        temp = monthDays(this.year, i);
                    }
                    if (this.isLeap == true && i == (leap + 1)) this.isLeap = false;
                    offset -= temp;
                }
                if (offset == 0 && leap > 0 && i == leap + 1) if (this.isLeap) {
                    this.isLeap = false;
                } else {
                    this.isLeap = true;
                    --i;
                }
                if (offset < 0) {
                    offset += temp;
                    --i;
                }
                this.month = i;
                this.day = offset + 1;
            }

            var nStr1 = new Array('', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十', '十一', '十二');
            var nStr2 = new Array('初', '十', '廿', '卅', '□');

            function GetcDay(d) {
                var s;
                switch (d) {
                    case 10:
                        s = '初十';
                        break;
                    case 20:
                        s = '二十';
                        break;
                    case 30:
                        s = '三十';
                        break;
                    default:
                        s = nStr2[Math.floor(d / 10)];
                        s += nStr1[d % 10];
                        break;
                }
                return (s);
            }

            function GetcMon(m) {
                if (m == 1) return '正';
                else return nStr1[m];
            }

            function getlunar() {
                var lObj = new Lunar(nyear, nmonth - 1, nday);
                lmonth = GetcMon(lObj.month);
                lday = GetcDay(lObj.day);
                lleap = lObj.isLeap;
                if (lleap == 1) {
                    lmonth = "闰" + lmonth;
                }
            }
            //阴历函数结束
            return Draw();
        },
        /**获取阴历 end*/
        //  获取阴历节日
        getLunarFestival(lm, ld) {
            /**
             * 计算农历每个月的天数, 参数为存储农历年的16进制
             * @param {Number} ly
             * @return {Array}
             * @eg {Function} lunarYearMonths(0x0b557)
             */
            const lunarYearMonths = function (ly) {
                //从高位第16位(1月)起向右移至低位第5位(12月)添加数组每项
                let monthArr = [];
                for (let i = 0x8000; i > 0x8; i >>= 1) {
                    monthArr.push((ly & i) ? 30 : 29);
                }
                //考虑是否有闰月天数
                if (hasLeapMonth(ly)) {
                    monthArr.splice(hasLeapMonth(ly), 0, leapMonthDays(ly));
                }
                return monthArr
            }
            // 初始化农历节日数组
            const lunarFestival = new Array(
                "0101 春节",
                "0107 人胜节",
                "0115 元宵节",
                "0120 天穿节",
                "0125 天仓节",
                "0201 中和节",
                "0202 春龙节(龙抬头)",
                "0212 花朝节",
                "0303 上巳节",
                "0408 浴佛节",
                "0505 端午节",
                "0606 晒衣节",
                "0707 乞巧节(七夕)",
                "0715 中元节",
                "0801 天医节",
                "0815 中秋节",
                "0909 重阳节",
                "1001 寒衣节",
                "1015 下元节",
                "1208 腊八节",
                "1224 祭灶节(小年)"
            );

            //阴历函数开始
            var lunarInfo = new Array(
                0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
                0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
                0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
                0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
                0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
                0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5b0, 0x14573, 0x052b0, 0x0a9a8, 0x0e950, 0x06aa0,
                0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
                0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b6a0, 0x195a6,
                0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
                0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x05ac0, 0x0ab60, 0x096d5, 0x092e0, //1990
                0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
                0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
                0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
                0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
                0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0,
                0x14b63);
            // 计算农历节日
            // ly lm ld 为农历年月日
            let lunar = null;
            lunarFestival.forEach((item, index) => {
                let str = item.split(" ");
                if (str[0] == `${lm < 10 ? "0" + lm : lm}${ld < 10 ? "0" + ld : ld}`) {
                    lunar = str[1];
                }
                //部分节日需要手动计算例如春节前一天除夕，清明前一天寒食节等等
                //考虑到闰正月和闰腊月计算相对复杂这里仅做粗略计算，严谨请参照(平气法已过时)定气法具体百度搜索相关资料做调整
                let lymArr = lunarYearMonths(lunarInfo[ly - 1900]);
                if (`${lm}${ld}` == `12${lymArr[lymArr.length - 1]}`) {
                    lunar = "除夕";
                }
                return lunar
            })
        },

        //  获取阳历节日
        getSolarFestival() {
            // 初始化公历节日数组（更多公历节日可自行在数组内添加相应的日期和名称即可）
            const gregorianFestival = new Array(
                "0101 元旦",
                "0214 情人节",
                "0307 女生节",
                "0308 妇女节",
                "0312 植树节",
                "0314 白色情人节",
                "0315 消费者权益日",
                "0401 愚人节",
                "0404 复活节",
                "0501 劳动节",
                "0504 青年节",
                "0510 母亲节",
                "0512 护士节",
                "0601 儿童节",
                "0620 父亲节",
                "0701 建党节",
                "0801 建军节",
                "0910 教师节",
                "0928 孔子诞辰",
                "1001 国庆节",
                "1006 老人节",
                "1024 联合国日",
                "1101 万圣节",
                "1125 感恩节",
                "1224 平安夜",
                "1225 圣诞节"
            );
            // 计算公历节日
            // sy sm sd 为传入年月日
            let gregorian = null;
            gregorianFestival.forEach((item, index) => {
                let str = item.split(" ");
                if (str[0] == `${sm}${sd}`) {
                    gregorian = str[1];
                }
            })
            return gregorian
        }
    }
}
</script>

<style scoped>
.calendar {
    /* width: 350px; */
    /* height: 300px; */
    /* border: 1px solid #909192; */
}

.fontS {
    font-size: 14px;
    /* font-weight: 600; */
}

.header {
    /* width: 340px; */
    height: 50px;
    border-bottom: 1px solid #909192;
    display: flex;
    align-items: center;
    justify-content: center;
}

.body {
    display: grid;
    grid-template-columns: repeat(7, 4em);
    grid-template-rows: repeat(7, 3.5em);
}

.body>div {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.last-month-day {
    color: gray;
}

.current-month-day {
    color: black;
}

.dateDayStyle {
    background-color: #d1d1d1;
    border-radius: 10px;
}

.current-day {
    color: blue;
}

.next-month-day {
    color: gray;
}
</style>